package com.autotest.nore.common.utils;

import org.graalvm.polyglot.HostAccess;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.graalvm.polyglot.Context;
import org.graalvm.polyglot.Value;

import java.util.HashMap;
import java.util.Map;

public class GraalVMScriptUtils {
    private static final Logger logger = LoggerFactory.getLogger(GraalVMScriptUtils.class);
    private static Context context; // 将 Context 存储为成员变量

    /**
     * 初始化 Context
     */
    public static void initializeContext() {
        if (context == null) {
            context = Context.newBuilder("js")
                    .allowAllAccess(true) // 允许所有访问
                    .allowHostAccess(HostAccess.ALL) // 允许访问主机对象
                    .allowHostClassLookup(className -> true) // 允许查找主机类
                    .build();
        }
    }
    /**
     * 执行 JavaScript 脚本
     */
    public static Object eval(String script, Map<String, String> variables) {
        // 创建新的上下文
        if (context == null) {
            initializeContext();
        }

        try {
            // 将变量注入到脚本的上下文中
            Value bindings = context.getBindings("js");
            for (Map.Entry<String, String> entry : variables.entrySet()) {
                bindings.putMember(entry.getKey(), entry.getValue());
            }

            // 执行脚本
            Value result = context.eval("js", script);
            return result.as(Object.class);
        } catch (Exception e) {
            logger.error("Script evaluation failed: " + e.getMessage(), e);
            throw new RuntimeException("Script evaluation failed: " + e.getMessage(), e);
        }

    }

    /**
     * 关闭 Context
     */
    public static void closeContext() {
        if (context != null) {
            context.close();
            context = null;
        }
    }

    /**
     * 获取脚本执行后的变量
     *
     * @return 脚本执行后的变量集合
     */
    public static Map<String, Object> getScriptVariables() {
        if (context == null) {
            return new HashMap<>();
        }

        Map<String, Object> scriptVariables = new HashMap<>();
        Value bindings = context.getBindings("js");
        Value result = context.eval("js", "Object.keys(this)");
        if (result.hasArrayElements()) {
            for (int i = 0; i < result.getArraySize(); i++) {
                String variableName = result.getArrayElement(i).asString();
                scriptVariables.put(variableName, bindings.getMember(variableName));
            }
        }

        return scriptVariables;
    }

}